package org.wm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.wm.constants.UserConstants;
import org.wm.domain.SysDictData;
import org.wm.domain.SysDictType;
import org.wm.exception.ServiceException;
import org.wm.mapper.SysDictDataMapper;
import org.wm.mapper.SysDictTypeMapper;
import org.wm.service.ISysDictTypeService;
import org.wm.utils.DictUtils;
import org.wm.utils.ServiceUtils;
import org.wm.utils.StringUtils;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 字典 业务层处理
 * (已按照 Mybatis-Plus 混合模式进行改造)
 */
@RequiredArgsConstructor
@Service
public class SysDictTypeServiceImpl extends ServiceImpl<SysDictTypeMapper, SysDictType> implements ISysDictTypeService {

    private final SysDictDataMapper dictDataMapper;

    @PostConstruct
    public void init() {
        loadingDictCache();
    }

    @Override
    public IPage<SysDictType> selectDictTypePage(Page<SysDictType> page, SysDictType dictType) {
        return baseMapper.selectDictTypeList(page, dictType);
    }

    @Override
    public List<SysDictType> selectDictTypeAll() {
        return baseMapper.selectDictTypeAll();
    }

    @Override
    public List<SysDictData> selectDictDataByType(String dictType) {
        List<SysDictData> dictDatas = DictUtils.getDictCache(dictType);
        if (!dictDatas.isEmpty()) {
            return dictDatas;
        }
        dictDatas = dictDataMapper.selectList(new LambdaQueryWrapper<SysDictData>().eq(SysDictData::getDictType, dictType).orderByAsc(SysDictData::getDictSort));
        if (!dictDatas.isEmpty()) {
            DictUtils.setDictCache(dictType, dictDatas);
            return dictDatas;
        }
        return null;
    }

    @Override
    public SysDictType selectDictTypeByType(String dictType) {
        return baseMapper.selectDictTypeByType(dictType);
    }

    @Override
    @Transactional
    public void deleteDictTypeByIds(Long[] dictIds) {
        for (Long dictId : dictIds) {
            SysDictType dictType = this.getById(dictId);
            long count = dictDataMapper.selectCount(new LambdaQueryWrapper<SysDictData>().eq(SysDictData::getDictType, dictType.getDictType()));
            if (count > 0) {
                throw new ServiceException(String.format("%1$s已分配,不能删除", dictType.getDictName()));
            }
            this.removeById(dictId);
            DictUtils.removeDictCache(dictType.getDictType());
        }
    }

    @Override
    public void loadingDictCache() {
        SysDictData dictData = new SysDictData();
        dictData.setStatus("0");

        // 使用 Wrapper 查询所有状态正常的字典数据
        List<SysDictData> allDictData = dictDataMapper.selectList(new LambdaQueryWrapper<SysDictData>().eq(SysDictData::getStatus, "0"));

        Map<String, List<SysDictData>> dictDataMap = allDictData.stream().collect(Collectors.groupingBy(SysDictData::getDictType));

        for (Map.Entry<String, List<SysDictData>> entry : dictDataMap.entrySet()) {
            List<SysDictData> sortedList = entry.getValue().stream()
                    .sorted(Comparator.comparing(SysDictData::getDictSort))
                    .collect(Collectors.toList());
            DictUtils.setDictCache(entry.getKey(), sortedList);
        }
    }

    @Override
    public void clearDictCache() {
        DictUtils.clearDictCache();
    }

    @Override
    public void resetDictCache() {
        clearDictCache();
        loadingDictCache();
    }

    @Override
    public boolean insertDictType(SysDictType dict) {
        boolean success = this.save(dict);
        if (success) {
            DictUtils.setDictCache(dict.getDictType(), null);
        }
        return success;
    }

    @Override
    @Transactional
    public boolean updateDictType(SysDictType dict) {
        SysDictType oldDict = this.getById(dict.getDictId());
        dictDataMapper.updateDictDataType(oldDict.getDictType(), dict.getDictType());
        boolean success = this.updateById(dict);
        if (success) {
            // 更新缓存
            List<SysDictData> dictDatas = dictDataMapper.selectList(
                    new LambdaQueryWrapper<SysDictData>().eq(SysDictData::getDictType, dict.getDictType())
            );
            DictUtils.setDictCache(dict.getDictType(), dictDatas);
        }
        return success;
    }

    @Override
    public String checkDictTypeUnique(SysDictType dict) {
        Long dictId = dict.getDictId() == null ? -1L : dict.getDictId();
        SysDictType dictType = this.getOne(new LambdaQueryWrapper<SysDictType>().eq(SysDictType::getDictType, dict.getDictType()));
        if (dictType != null && !dictType.getDictId().equals(dictId)) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }
}